"""
函数：什么是函数-函数就是类似java里面的方法，可以被其他地方调用的代码块
    java例子:public String getByName(String userName)
"""
import math

"""
Python语法-def语句

"""


def all_print():
    print("今天在下雨")
    print("明天不下雨")
    print("后天要下雨")


# 函数的调用
all_print()

"""
和java一样，函数也区分形参，实参，入参和出参，返回值
形参和实参:
    java代码:public String getByName(String userName)
    形参就是userName 代表这个参数要传String类型的数据，至于什么无所谓
    实参就是调用时，例如getByName（"张三"）-这个张三就是实际传进去的参数
返回值: return的内容
    无返回值->java类似 void返回值
    一个返回值->java类似
    多个返回值-python可以返回多个返回值.例如游戏里面的移动就是一个坐标移动到另一坐标,给出角度和位移就能实现
空函数:pass关键字的使用 if里面 函数里面都可以用,占位符比如现在还没想好怎么写函数的代码，就可以先放一个pass，让代码能运行起来。

"""

# pass 关键字
def pass_demo():
    pass


def if_pass_demo():
    if 1 == 1:
        pass


"""
做一个简易版的计算器，用户输入两个数字和计算符号，得到计算结果-只计算加减乘除
"""


def cal_result(number1, number2, calType):
    if not number1.isdigit():
        return "被计算数字必须为数字类型"
    if not number2.isdigit():
        return "计算数字必须为数字类型"
    if str(calType) == "+":
        return int(number1) + int(number2)
    elif str(calType == "-"):
        return int(number1) - int(number2)
    elif str(calType == "-"):
        return int(number1) - int(number2)
    elif str(calType == "*"):
        return int(number1) * int(number2)
    elif str(calType == "/"):
        return int(number1) / int(number2)
    else:
        return "目前只能支持加减乘除"


# 函数调用
# number_1=input("输入第一个数")
# number_2=input("请输入第二个数字")
# calType=input("请输入计算方式")
# print("当前结果是",cal_result(number_1,number_2,calType))

"""
多返回值的函数-看起来是多返回值,其实还是一个只是返回值是一个Tuple,按照位置能拿到里面的值而已
"""


def move(x, y, step, angle=0):
    nx = x + step * math.cos(angle)
    ny = y - step * math.sin(angle)
    return nx, ny


# 函数调用
x, y = move(100, 100, 100, math.pi / 6)
print(x, y)
res = move(100, 100, 100, math.pi / 6)
print(res)
"""
python的参数:
    python的函数和java的方法一样，功能强大只需要将方法写好等调用即可
    和java不同，java的方法比较死入参类型固定。出参也进行了泛型。
    python函数参数:
        1位置参数-java一样。形参占位，但是python的参数类型没有数据类型限制，java对于参数做了泛型，只能传指定类型
        2关键字参数-传递参数的时候，可以不用考虑位置。直接传递关键字=实际值，这样就不用按照顺序传参
            混合使用关键字和位置参数时，必须将位置参数写到前面
        3默认参数。有的参数定时可以定义默认值，在传参时可以选择不传参也不报错
"""
# 位置参数
def mixed_result(num):
    if not str(num).isdigit():
        print("计算的参数必须为整数类型")
    else:
        print("num*num",int(num)*int(num))
mixed_result(3)
mixed_result("张三")

def get_by_user_name(username,age,sex):
    print("当前用户名",username,"当前用户年龄",age,"当前用户性别",sex)
# 关键字参数
get_by_user_name(username="张三",sex="男",age=19)

#  默认参数
def getByUserCondition(userName="张三", age=19, sex="男"):
    print("用户名字是", userName, "年龄", age, "性别", sex)

def getByUserConditionType(userName="张三", age=19, sex="男", hobby="打篮球", memberLevel=3, member="篮球会员"):
    print("用户名字是", userName, "年龄", age, "性别", sex)
    print("用户爱好是", hobby, "用户会员等级", memberLevel, "用户会员名", member)

getByUserCondition("张五", 11, "女")
# 缺少参数函数调用
getByUserCondition("张五", "女")
getByUserCondition("张五", sex="女")
# 组合调用关键字参数，默认参数，位置参数 一旦使用了关键字参数，后面所有都要用关键字参数，不然会报错
getByUserConditionType("张五", memberLevel=5, sex="女", member="足球新时代")


"""
可变参数 类似于Java方法传参的（...String name）这种传递方式。这种方式参数个数不固定。不传也不报错
    java参数传递的方式都是值传递。传参不会影响原来变量的值。而是便来变量值得引用
可变参数可以和其他类型的参数配合使用,spring源码里面用得比较多
"""
# 求任意数字相加得和
def cal_math_res(*num):
    sum=0
    for n in num :
        sum+=n
    print("当前数字得和是",sum)
cal_math_res(1)
cal_math_res(1,2,1,1,1,1)
cal_math_res()

def user_desc(name,age,sex,*args):

    index='附加属性:'
    for arg in args:
        index+=arg
        index+=","

    # 截取掉最后一个,用到了切片
    index=index[0:-1]
    print("当前用户名",name,"年龄",age,"性别",sex,index)

user_desc("张三",15,"男","升高115","体重117","眼睛近视")



"""
参数的装包和拆包
参数的装包:
    在定义参数时，如果再参数前面加上一个*,就代表这个参数被装包。他所有的实参都会被放进一个元组中
        注意，python中带*的参数只能有一个
        *参数不一定非要在末尾，也能在中间，但是传参时*参数之后想要传参必须关键字传参
            -当方法开头出现一个*,那么代表这个方法的参数都必须关键字传参
    在定义参数时，入伏哦在参数前面加上**，那么这些参数所有的实参都会被放进一个字典中
            字典的key就是参数名字，value就是参数的值
            **这一种只能写在最后一位参数
            在实参时，**表示的参数必须传键值对
参数的解包:
    在实参传递时，也可以将实参作为元组加上*,或者字典的实参加上**进行解包。这样他就会把数组或者依次写入到参数中
    前提是：个数相同，
"""
def user_fn(name,*args,age,sex):
    index='附加属性:'
    for arg in args:
        index+=arg
        index+=","
    print("当前用户名",name,"年龄",age,"性别",sex,index)

user_fn("张三","李四","王五","赵六",age=19,sex="男")

def user_fn1(*,a,b,c):
    print(a,b,c)
user_fn1(a=1,b=2,c=3)

def user_fn2(a,b,**c):
    print(type(c))
user_fn2(3,4,key=5)

def user_fn3(a,b,c):
    print("a=",a,"b=",b,"c=",c)
pam=(1,2,3)
user_fn3(*pam)
# 字典解包的时候,key值必须和参数的形参定义名字一样 不然无法解包
pam1={'d':100,"b":20,"c":50}
user_fn3(**pam1)